﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using agsXMPP;
using agsXMPP.protocol.client;
using agsXMPP.protocol.iq.roster;
using agsXMPP.protocol.iq.vcard;
using Mammoth.Configurations;
using Mammoth.Entities;
using Mammoth.Events;

namespace Mammoth.Services
{
    public partial class GTalkService : IGTalkService 
    {
        public event EventHandler<SubscriptionRequestEventArgs> SubscriptionRequest;
        public event EventHandler<ServiceMessageEventArgs> Message;
        public event EventHandler<ServiceErrorEventArgs> Error;
        public event EventHandler<ServiceEventArgs> FriendListLoad;
        public event EventHandler<ServiceEventArgs> Login;
        public event EventHandler<ServiceEventArgs> Logout;
        public event EventHandler AccountListChange;

        public IList<BuddyEntity> BuddyList { get; private set; }
        public IList<AccountEntity> AccountList { get; private set; }
        public IGTalkConfiguration Configuration { get; private set; }

        private Dictionary<string, XmppClientConnection> clients;

        public GTalkService(IGTalkConfiguration configuration)
        {
            AccountList = new List<AccountEntity>();
            BuddyList = new List<BuddyEntity>();
            clients = new Dictionary<string, XmppClientConnection>();
            Configuration = configuration;
            foreach (var item in Configuration.Accounts)
                AccountList.Add((AccountEntity)item);
        }

        public void LoginAll()
        {
            foreach (var item in AccountList)
            {
                if (item.IsAutoLogin)
                    DoLogin(item.Email, item.Password);
            }
        }

        public void AddAccount(string email, string password, bool isAutoLogin)
        {
            var test = AccountList.FirstOrDefault(x => x.Email == email);
            if (test != null)
                AccountList.Remove(test);

            var el = new GTalkAccountConfigElement() { Email = email, Password = password, IsAutoLogin = isAutoLogin };
            var account = (AccountEntity)el;
            AccountList.Add(account);
            if (isAutoLogin)
                DoLogin(email, password);
            Configuration.Accounts.Add(el);
            Configuration.Save();
            OnAccountListChange(email);
        }

        public void DoLogin(string email, string password)
        {
            if (email.Contains("@gmail.com"))
            {
                var account = AccountList.FirstOrDefault(x => x.Email == email);
                account.State = AccountState.Busy;

                var client = GetXmppClient(email);
                Jid jid = new Jid(email);
                client.Username = jid.User;
                client.Password = password;
                client.Server = jid.Server;
                client.Open();
            }
            else
            {
                OnError(email, ServiceErrorType.InvalidAccount);
            }
        }

        public void DoLogout(string serviceEmail)
        {
            var client = GetXmppClient(serviceEmail);
            client.Close();
            var account = AccountList.FirstOrDefault(x => x.Email == serviceEmail);
            if (account != null)
                account.State = AccountState.Logoff;
            OnLogout(serviceEmail);
        }

        public void ApproveSubscirption(string serviceEmail, string buddyEmail)
        {
            var client = GetXmppClient(serviceEmail);
            PresenceManager manager = new PresenceManager(client);
            manager.ApproveSubscriptionRequest(new Jid(buddyEmail));
        }

        public void SendMessage(string serviceEmail, string buddyEmail, string message)
        {
            var client = GetXmppClient(serviceEmail);
            client.Send(new Message(new Jid(buddyEmail), MessageType.chat, message));
        }


        public void Subscribe(string serviceEmail, string buddyEmail)
        {
            var client = GetXmppClient(serviceEmail);
            PresenceManager manager = new PresenceManager(client);
            manager.Subscribe(new Jid(buddyEmail));
        }


        public void RemoveAccount(string serviceEmail)
        {
            var client = GetXmppClient(serviceEmail);
            ReleaseClient(client);
            var account = AccountList.FirstOrDefault(x => x.Email == serviceEmail);
            AccountList.Remove(account);

            Configuration.Accounts.Clear();

            foreach (var item in AccountList)
            {
                var el = (GTalkAccountConfigElement)item;
                Configuration.Accounts.Add(el);
            }

            Configuration.Save();
            if (AccountListChange != null)
                AccountListChange(this, new EventArgs());
        }


        public void BlockBuddy(string serviceEmail, string buddyEmail)
        {
            throw new NotImplementedException();
        }
    }
}
